Try harder to discriminate Shift-F10 and F10
authorMatthias Clasen <mclasen@redhat.com>
Sun, 2 Sep 2012 02:51:18 +0000 (22:51 -0400)
committerMatthias Clasen <mclasen@redhat.com>
Sun, 2 Sep 2012 03:25:18 +0000 (23:25 -0400)
A change in xkeyboard-config 2.4.1 made it so that function keys
now have a shift level which has the same symbol, but 'eats' the
shift modifier. This would ordinarily make it impossible for us
to discriminate between these key combinations.

This commit tries harder to discriminate in 2 ways:
- XKB has a mechanism to tell us when a modifier should not be
  consumed even though it was used in determining the level.
  We now respect such 'preserved' modifiers. This does not fix
  the Shift-F10 vs F10 problem yet, since xkeyboard-config does
  not currently mark Shift as preserved for function keys.
- Don't consume modifiers that do not change the symbol. For
  the function keys, the symbol on the shift level is the same
  as the base level, so we don't consider Shift consumed.

For more background on the xkeyboard-config change, see
https://bugs.freedesktop.org/show_bug.cgi?id=45008

https://bugzilla.gnome.org/show_bug.cgi?id=661973

gdk/x11/gdkkeys-x11.c

index ac8e401ebf742aff70910a3360048236e16851b2..9d06cbaeafce0bb0734750c4f626b8cb4c7a134d 100644 (file)
@@ -1113,6 +1113,8 @@ MyEnhancedXkbTranslateKeyCode(register XkbDescPtr     xkb,
         int found = 0;
 
         for (i=0,entry=type->map;i<type->map_count;i++,entry++) {
+            if (!entry->active)
+              continue;
             if (mods_rtrn) {
                 int bits = 0;
                 unsigned long tmp = entry->mods.mask;
@@ -1123,14 +1125,22 @@ MyEnhancedXkbTranslateKeyCode(register XkbDescPtr     xkb,
                 }
                 /* We always add one-modifiers levels to mods_rtrn since
                  * they can't wipe out bits in the state unless the
-                 * level would be triggered. But return other modifiers
-                 *
+                 * level would be triggered. But not if they don't change
+                 * the symbol (otherwise we can't discriminate Shift-F10
+                 * and F10 anymore). And don't add modifiers that are
+                 * explicitly marked as preserved, either.
                  */
-                if (bits == 1 || (mods&type->mods.mask)==entry->mods.mask)
-                    *mods_rtrn |= entry->mods.mask;
+                if ((bits == 1 && syms[col+entry->level] != syms[col]) ||
+                    (mods&type->mods.mask) == entry->mods.mask)
+                  {
+                    if (type->preserve)
+                      *mods_rtrn |= (entry->mods.mask & ~type->preserve[i].mask);
+                    else
+                      *mods_rtrn |= entry->mods.mask;
+                  }
             }
 
-            if (!found&&entry->active&&((mods&type->mods.mask)==entry->mods.mask)) {
+            if (!found&&((mods&type->mods.mask)==entry->mods.mask)) {
                 col+= entry->level;
                 if (type->preserve)
                     preserve= type->preserve[i].mask;